package net.jiastudy.web.rest.controller.targettask;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.baomidou.mybatisplus.plugins.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.jiastudy.biz.datasync.TaskImporter;
import net.jiastudy.biz.sys.entity.Dept;
import net.jiastudy.biz.sys.service.DeptService;
import net.jiastudy.biz.targettask.entity.*;
import net.jiastudy.biz.targettask.service.TargetTaskService;
import net.jiastudy.core.base.BaseController;
import net.jiastudy.core.exception.ServiceException;
import net.jiastudy.core.utils.UploadUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.annotation.Target;
import java.text.ParseException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
@RequestMapping("/targettask")
@Api(value = "TargetTaskController  目标任务")
public class TargetTaskController extends BaseController {
    @Resource
    private TargetTaskService targetTaskService;
    @Resource
    private DeptService deptService;
    @Value("${upload.path.base}")
    private String basePath;

    @RequestMapping(path = "/drag", method = RequestMethod.PUT)
    @ApiOperation(value = "任务树形", notes = "")
    public boolean taskDrag(@RequestBody List<TaskDrag> taskDrags) {
        targetTaskService.taskDrag(taskDrags);
        return true;
    }

    @RequestMapping(path = "/tree", method = RequestMethod.GET)
    @ApiOperation(value = "任务树形", notes = "")
    public YearTaskTree taskTree(@RequestParam Long yearId) {
        return targetTaskService.getYearTaskTree(yearId);
    }

    @RequestMapping(path = "/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "获取单个任务", notes = "")
    public TargetTask get(@PathVariable Long id) {
        return targetTaskService.getTargetTask(id);
    }

    @RequestMapping(path = "/{id}", method = RequestMethod.PUT)
    @ApiOperation(value = "更新单个任务", notes = "")
    public TargetTask edit(@PathVariable Long id, @RequestBody TargetTask targetTask) {
        targetTask.setId(id);

        return targetTaskService.updateTargetTask(targetTask);
    }

    @RequestMapping(path = "/{id}/children", method = RequestMethod.GET)
    @ApiOperation(value = "查找下一级任务", notes = "")
    public List<TargetTask> findChildren(@PathVariable Long id, @RequestParam Long year) {
        return targetTaskService.findTargetTasksByParentIdAndYear(id, year);
    }

    @RequestMapping(path = "/{id}", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除任务", notes = "")
    public Boolean deleteTask(@PathVariable Long id) {
        return targetTaskService.deleteTask(id);
    }

    @RequestMapping(method = RequestMethod.POST)
    @ApiOperation(value = "创建任务", notes = "")
    public boolean create(@RequestBody TargetTask targetTask) {
        targetTaskService.createTargetTasks(targetTask);

        return true;
    }

    @RequestMapping(path = "/{id}/pass", method = RequestMethod.PUT)
    @ApiOperation(value = "审核单个任务", notes = "")
    public TargetTask pass(@PathVariable Long id) {
        return targetTaskService.passTargetTask(id);
    }
    
    @RequestMapping(path = "/{id}/batchpass", method = RequestMethod.PUT)
    @ApiOperation(value = "批量审核通过", notes = "")
    public Boolean batchPass(@PathVariable Long id) {
        return targetTaskService.batchPassTargetTasks(id);
    }
    
    @RequestMapping(path = "/{id}/batchunpass", method = RequestMethod.PUT)
    @ApiOperation(value = "批量取消审核", notes = "")
    public Boolean batchUnPass(@PathVariable Long id) {
        return targetTaskService.batchCancelPassTargetTasks(id);
    }

    @RequestMapping(path = "/{id}/unpass", method = RequestMethod.PUT)
    @ApiOperation(value = "取消审核单个任务", notes = "")
    public TargetTask unpass(@PathVariable Long id) {
        return targetTaskService.cancelPassTargetTask(id);
    }

    @RequestMapping(path = "/report", method = RequestMethod.GET)
    @ApiOperation(value = "目标任务统计", notes = "")
    public List<TaskReportVo> report(@RequestParam Long year, @RequestParam Long deptId) {
        return targetTaskService.getTaskReportByYearAndDeptId(year, deptId);
    }

    @RequestMapping(path = "/dept/{deptId}/assessment_depts", method = RequestMethod.GET)
    @ApiOperation(value = "获取考核部门", notes = "")
    public List<Dept> assessmentDepts(@PathVariable Long deptId, @RequestParam Long yearId) {
        return targetTaskService.findAssessmentDeptsByAssessmentedDeptIdAndYearId(deptId, yearId);
    }

    @RequestMapping(path = "/summary", method = RequestMethod.GET)
    @ApiOperation(value = "获取任务汇总情况", notes = "")
    public List<TargetTask> findSummary(@RequestParam Map<String, Object> conditions) {
        return targetTaskService.findTaskSummary(conditions);
    }

    @RequestMapping(path = "/import", method = RequestMethod.POST)
    @ApiOperation(value = "任务导入", notes = "")
    public boolean importTask(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty() || file.getSize() == 0) {
            return true;
        }
        Date now = new Date();
        String fileName = file.getOriginalFilename();
        fileName = "/" + now.getTime() + fileName;

        String filePath = UploadUtil.TEMP_PATH + UploadUtil.makeFileDir(now);
        boolean bool = UploadUtil.mkdirs(basePath + filePath);
        if (!bool) {
            logger.error("创建目录失败，请检查权限");
            throw new ServiceException("500", "创建目录失败，请检查权限");
        }
        java.io.File dest = new java.io.File(basePath + filePath + fileName);
        try {
            file.transferTo(dest);
        } catch (IllegalStateException | IOException e) {
            logger.error("文件上传出错了：", e);
        }

        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        ExcelImportResult<TaskImporter> list = ExcelImportUtil.importExcelMore(
                dest, TaskImporter.class, params);
        targetTaskService.importTasks(list.getList());

        return true;
    }

    @RequestMapping(path = "/export", method = RequestMethod.GET)
    @ApiOperation(value = "任务导出", notes = "")
    public void exportTask(@RequestParam Long yearId, @RequestParam Long deptId, HttpServletResponse response) throws IOException, ParseException {
        TaskYear taskYear = targetTaskService.getTaskYear(yearId);
        StringBuilder fileName = new StringBuilder();
        if (deptId.equals(0)) {
            fileName.append(taskYear.getTitle() + "任务.xls");
        } else {
            Dept dept = deptService.getDept(deptId);
            if (null != dept) {
                fileName.append(taskYear.getTitle() + "-" + dept.getName() + "任务.xls");
            } else {
                fileName.append(taskYear.getTitle() + "任务.xls");
            }
        }

        List<TargetTaskTree> taskTreeList = targetTaskService.getTaskTree(yearId);
        List<TargetTask> tasks = targetTaskService.findTasksByYear(yearId);
        Map<Long, TargetTask> taskMap = new HashMap<>();
        for (TargetTask task: tasks) {
            taskMap.put(task.getId(), task);
        }

        List<TaskExport> exportList = new ArrayList<>();
        for (TargetTaskTree taskTree : taskTreeList) {
            if (taskMap.containsKey(taskTree.getId())) {
                TargetTask tmpTask = taskMap.get(taskTree.getId());

                TaskExport export = new TaskExport();
                if (null != tmpTask.getAssessmentElements()) {
                    export.setElements(delHtml(tmpTask.getAssessmentElements()));
                }
                if (null != tmpTask.getAssessmentStandard()) {
                    export.setStandard(delHtml(tmpTask.getAssessmentStandard()));
                }
                export.setTopTask(tmpTask.getTitle());
                export.setOrigin(tmpTask.getOrigin());
                if (null != tmpTask.getOriginatedDept()) {
                    export.setOriginatedDeptName(tmpTask.getOriginatedDept().getName());
                }
                if  (null != tmpTask.getReceiveDept()) {
                    export.setReceiveDeptName(tmpTask.getReceiveDept().getName());
                }
                if (null == deptId || deptId == 0 || (null != deptId && deptId.equals(tmpTask.getReceiveDeptId()))) {
                    exportList.add(export);
                }
                if (null != taskTree.getChildren() && !taskTree.getChildren().isEmpty()) {
                    for (TargetTaskTree firstTaskTree : taskTree.getChildren()) {
                        if (taskMap.containsKey(firstTaskTree.getId())) {
                            TargetTask fristTmpTask = taskMap.get(firstTaskTree.getId());

                            TaskExport firstExport = new TaskExport();
                            firstExport.setTopTask(export.getTopTask());
                            if (null != fristTmpTask.getAssessmentElements()) {
                                firstExport.setElements(delHtml(fristTmpTask.getAssessmentElements()));
                            }

                            if (null != fristTmpTask.getAssessmentStandard()) {
                                firstExport.setStandard(delHtml(fristTmpTask.getAssessmentStandard()));
                            }
                            firstExport.setFirstTask(fristTmpTask.getTitle());
                            firstExport.setOrigin(fristTmpTask.getOrigin());

                            if (null != fristTmpTask.getOriginatedDept()) {
                                firstExport.setOriginatedDeptName(fristTmpTask.getOriginatedDept().getName());
                            }
                            if  (null != fristTmpTask.getReceiveDept()) {
                                firstExport.setReceiveDeptName(fristTmpTask.getReceiveDept().getName());
                            }
                            if (null == deptId || deptId == 0 || (null != deptId && deptId.equals(fristTmpTask.getReceiveDeptId()))) {
                                exportList.add(firstExport);
                            }

                            if (null != firstTaskTree.getChildren() && !firstTaskTree.getChildren().isEmpty()) {
                                for (TargetTaskTree secondTaskTree : firstTaskTree.getChildren()) {
                                    if (taskMap.containsKey(secondTaskTree.getId())) {
                                        TargetTask secondTmpTask = taskMap.get(secondTaskTree.getId());

                                        TaskExport secondExport = new TaskExport();
                                        if (null != secondTmpTask.getAssessmentElements()) {
                                            secondExport.setElements(delHtml(secondTmpTask.getAssessmentElements()));
                                        }

                                        if (null != secondTmpTask.getAssessmentStandard()) {
                                            secondExport.setStandard(delHtml(secondTmpTask.getAssessmentStandard()));
                                        }
                                        secondExport.setOrigin(secondTmpTask.getOrigin());
                                        secondExport.setTopTask(firstExport.getTopTask());
                                        secondExport.setFirstTask(firstExport.getFirstTask());
                                        secondExport.setSecondTask(secondTmpTask.getTitle());

                                        if (null != secondTmpTask.getOriginatedDept()) {
                                            secondExport.setOriginatedDeptName(secondTmpTask.getOriginatedDept().getName());
                                        }
                                        if  (null != secondTmpTask.getReceiveDept()) {
                                            secondExport.setReceiveDeptName(secondTmpTask.getReceiveDept().getName());
                                        }
                                        if (null == deptId || deptId == 0 || (null != deptId && deptId.equals(secondTmpTask.getReceiveDeptId()))) {
                                            exportList.add(secondExport);
                                        }

                                        if (null != secondTaskTree.getChildren() && !secondTaskTree.getChildren().isEmpty()) {
                                            for (TargetTaskTree thirdTaskTree : secondTaskTree.getChildren()) {
                                                if (taskMap.containsKey(thirdTaskTree.getId())) {
                                                    TargetTask thirdTmpTask = taskMap.get(thirdTaskTree.getId());

                                                    TaskExport thirdExport = new TaskExport();
                                                    if (null != thirdTmpTask.getAssessmentElements()) {
                                                        thirdExport.setElements(delHtml(thirdTmpTask.getAssessmentElements()));
                                                    }

                                                    if (null != thirdTmpTask.getAssessmentStandard()) {
                                                        thirdExport.setStandard(delHtml(thirdTmpTask.getAssessmentStandard()));
                                                    }
                                                    thirdExport.setTopTask(secondExport.getTopTask());
                                                    thirdExport.setFirstTask(secondExport.getFirstTask());
                                                    thirdExport.setSecondTask(secondExport.getSecondTask());
                                                    thirdExport.setThirdTask(thirdTmpTask.getTitle());
                                                    thirdExport.setOrigin(thirdTmpTask.getOrigin());

                                                    if (null != thirdTmpTask.getOriginatedDept()) {
                                                        thirdExport.setOriginatedDeptName(thirdTmpTask.getOriginatedDept().getName());
                                                    }
                                                    if  (null != thirdTmpTask.getReceiveDept()) {
                                                        thirdExport.setReceiveDeptName(thirdTmpTask.getReceiveDept().getName());
                                                    }
                                                    if (null == deptId || deptId == 0 || (null != deptId && deptId.equals(thirdTmpTask.getReceiveDeptId()))) {
                                                        exportList.add(thirdExport);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), TaskExport.class, exportList);

        UploadUtil.setFileDownloadHeader(response, fileName.toString());
        workbook.write(response.getOutputStream());
    }

    private String delHtml(String htmlStr) {
        String regEx_script="<script[^>]*?>[\\s\\S]*?<\\/script>";
        String regEx_style="<style[^>]*?>[\\s\\S]*?<\\/style>";
        String regEx_html="<[^>]+>";

        Pattern p_script=Pattern.compile(regEx_script,Pattern.CASE_INSENSITIVE);
        Matcher m_script=p_script.matcher(htmlStr);
        htmlStr = m_script.replaceAll("");

        Pattern p_style=Pattern.compile(regEx_style,Pattern.CASE_INSENSITIVE);
        Matcher m_style=p_style.matcher(htmlStr);
        htmlStr = m_style.replaceAll("");

        Pattern p_html=Pattern.compile(regEx_html,Pattern.CASE_INSENSITIVE);
        Matcher m_html=p_html.matcher(htmlStr);
        htmlStr = m_html.replaceAll("");

        return htmlStr.trim();
    }
}
